package com.gitee.ixtf.mongo

import com.gitee.ixtf.core.DefaultOperator
import com.gitee.ixtf.core.IEntity
import com.gitee.ixtf.core.IEntityLoggable
import java.util.*
import org.bson.BsonDocument
import org.bson.Document
import org.bson.codecs.pojo.annotations.BsonId

data class JmongoRef<T : MongoEntityBase>(
    val databaseName: String? = null,
    val collectionName: String,
    val id: String,
)

abstract class MongoEntityBase : IEntity {
  @field:BsonId override lateinit var id: String
  override var deleted = false

  override fun equals(other: Any?): Boolean {
    if (this === other) return true
    if (javaClass != other?.javaClass) return false
    other as MongoEntityBase
    return id == other.id
  }

  override fun hashCode(): Int {
    return id.hashCode()
  }
}

abstract class MongoEntityLoggable : MongoEntityBase(), IEntityLoggable {
  override var creator: DefaultOperator? = null
  override var createDateTime: Date? = null
  override var modifier: DefaultOperator? = null
  override var modifyDateTime: Date? = null
}

class MongoEntityMetadata(private val jmongo: Jmongo, private val clazz: Class<*>) {
  private val annoMongoEntity by lazy {
    if (clazz.isAnnotationPresent(MongoEntity::class.java))
        clazz.getAnnotation(MongoEntity::class.java)
    else null
  }
  val database by lazy {
    annoMongoEntity?.database?.takeIf { it.isNotBlank() }?.let { jmongo.client.getDatabase(it) }
        ?: jmongo.database
  }
  private val collectionName by lazy {
    annoMongoEntity?.collection?.takeIf { it.isNotBlank() } ?: "T_${clazz.simpleName}"
  }
  val collection by lazy { database.getCollection<Document>(collectionName) }
  val bsonCollection by lazy { database.getCollection<BsonDocument>(collectionName) }
  val entityCollection by lazy { database.getCollection(collectionName, clazz) }
}
